#ifndef ____RING_QUEUE_HPP____
#define ____RING_QUEUE_HPP____

#include <iostream>
#include <vector>
#include "sem.hpp"
#include "mutex.hpp"
#include<unistd.h>


template <class T>
class Ring_Queue
{
public:
    Ring_Queue()
        : _rq(cap), _cap(cap)
    {
    }

    void push(const T &_data)
    {
        _Space.P();

        {
            AutoMutex _lock(_p_mutex);
            _rq[_p_index++] = _data;
            _p_index %= _cap;
        }

        _DataSpace.V();
    }

    T Pop()
    {
        _DataSpace.P();
        T _data = T();
        {
            AutoMutex _lock(_c_mutex);
            _data = _rq[_c_index++];
            _c_index %= _cap;
        }

        _Space.V();
        return _data;
    }

    ~Ring_Queue()
    {
    }

private:
    std::vector<T> _rq;
    size_t _cap;
    int _p_index = 0;
    int _c_index = 0;
    wyc_Sem::Sem _Space;
    wyc_Sem::Sem _DataSpace = 0;
    Mutex _p_mutex;
    Mutex _c_mutex;
};

#endif